package cn.snowsoft.iot.module.warning.service.warning.rule;

import cn.snowsoft.iot.framework.common.pojo.CommonResult;
import cn.snowsoft.iot.module.warning.controller.admin.home.vo.RuleUseCountVO;
import cn.snowsoft.iot.module.warning.controller.admin.warning.rule.vo.WarningRuleVO;
import cn.snowsoft.iot.module.warning.dal.dataobject.warning.config.WarningDO;
import cn.snowsoft.iot.module.warning.dal.dataobject.warning.rule.WarningRuleDO;
import cn.snowsoft.iot.module.warning.dal.mysql.warning.rule.WarningRuleMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class WarningRuleServiceImpl extends ServiceImpl<WarningRuleMapper, WarningRuleDO> implements IWarningRuleService {

    @Override
    public CommonResult<Object> saveRule(WarningRuleDO warningDO) {
        if (warningDO.getProcessingType().isEmpty()) {
            return CommonResult.error(400, "参数错误！");
        }
        String timedSql = timeType(warningDO);

        warningDO.setRuleSql(timedSql);
        saveOrUpdate(warningDO);
        return CommonResult.success(warningDO);
    }

    @Override
    public IPage<WarningRuleDO> selectWarningPage(WarningRuleVO ruleVO) {
        IPage<WarningDO> page = new Page<>(ruleVO.getPageNo(), ruleVO.getPageSize());
        return baseMapper.selectProductPage(page, ruleVO);
    }

    @Override
    public Integer getRuleCount() {
        return baseMapper.getRuleCount();
    }


    public String selectType(WarningRuleDO warningDO) {
        Integer conditionType = warningDO.getConditionType();
        String ruleThreshold;
        String[] split;
        if (!warningDO.getProcessingType().equals("string")) {
            switch (conditionType) {
                case 1:
                    return "=" + " " + warningDO.getRuleThreshold();
                case 2:
                    return "!=" + " " + warningDO.getRuleThreshold();
                case 3:
                    return ">" + " " + warningDO.getRuleThreshold();
                case 4:
                    return ">=" + " " + warningDO.getRuleThreshold();
                case 5:
                    return "<" + " " + warningDO.getRuleThreshold();
                case 6:
                    return "<=" + " " + warningDO.getRuleThreshold();
                case 7:
                    ruleThreshold = warningDO.getRuleThreshold();
                    split = ruleThreshold.split("~");
                    return "BETWEEN" + " " + split[0] + " AND " + split[1];
                case 8:
                    ruleThreshold = warningDO.getRuleThreshold();
                    split = ruleThreshold.split("~");
                    return "NOT BETWEEN" + " " + split[0] + " AND " + split[1];
                case 9:
                    ruleThreshold = warningDO.getRuleThreshold();
                    split = ruleThreshold.split("~");
                    return "IN" + " (" + split[0] + " , " + split[1] + ")";
                case 10:
                    ruleThreshold = warningDO.getRuleThreshold();
                    split = ruleThreshold.split("~");
                    return "NOTIN" + " (" + split[0] + " , " + split[1] + ")";
                default:
                    return null;
            }
        } else {
            switch (conditionType) {
                case 1:
                    return "=" + " '" + warningDO.getRuleThreshold() + "'";
                case 2:
                    return "!=" + " '" + warningDO.getRuleThreshold() + "'";
                case 3:
                    return ">" + " '" + warningDO.getRuleThreshold() + "'";
                case 4:
                    return ">=" + " '" + warningDO.getRuleThreshold() + "'";
                case 5:
                    return "<" + " '" + warningDO.getRuleThreshold() + "'";
                case 6:
                    return "<=" + " '" + warningDO.getRuleThreshold() + "'";
                case 7:
                    ruleThreshold = warningDO.getRuleThreshold();
                    split = ruleThreshold.split("~");
                    return "BETWEEN" + " '" + split[0] + "' AND '" + split[1] + "'";
                case 8:
                    ruleThreshold = warningDO.getRuleThreshold();
                    split = ruleThreshold.split("~");
                    return "NOT BETWEEN" + " '" + split[0] + "' AND '" + split[1] + "'";
                case 9:
                    ruleThreshold = warningDO.getRuleThreshold();
                    split = ruleThreshold.split("~");
                    return "IN" + " ('" + split[0] + "' , '" + split[1] + "')";
                case 10:
                    ruleThreshold = warningDO.getRuleThreshold();
                    split = ruleThreshold.split("~");
                    return "NOTIN" + " ('" + split[0] + "' , '" + split[1] + "')";
                default:
                    return null;
            }
        }
    }

    public String computeType(WarningRuleDO warningDO) {
        switch (warningDO.getComputeType()) {
            case 1:
                return "点位 ";
            case 2:
                return "lag(点位) " + "OVER (PARTITION BY deviceCode = 设备)";
            case 3:
                return "avg(点位) ";
            case 4:
                return "max(点位) ";
            case 5:
                return "min(点位) ";
            case 6:
                return "sum(点位) ";
            case 7:
                return "count(点位) ";
            default:
                return "";
        }
    }

    public String timeType(WarningRuleDO warningDO) {
        switch (warningDO.getTimeType()) {
            case 1:
                return "GROUP BY TUMBLINGWINDOW(ms," + warningDO.getTimeValue() + ") " + "FILTER (WHERE deviceCode = 设备) " + "HAVING " + computeType(warningDO) + selectType(warningDO);
            case 2:
                return "GROUP BY TUMBLINGWINDOW(ss," + warningDO.getTimeValue() + ") " + "FILTER (WHERE deviceCode = 设备) " + "HAVING " + computeType(warningDO) + selectType(warningDO);
            case 3:
                return "GROUP BY TUMBLINGWINDOW(mi," + warningDO.getTimeValue() + ") " + "FILTER (WHERE deviceCode = 设备) " + "HAVING " + computeType(warningDO) + selectType(warningDO);
            case 4:
                return "GROUP BY TUMBLINGWINDOW(hh," + warningDO.getTimeValue() + ") " + "FILTER (WHERE deviceCode = 设备) " + "HAVING " + computeType(warningDO) + selectType(warningDO);
            case 5:
                return "GROUP BY TUMBLINGWINDOW(dd," + warningDO.getTimeValue() + ") " + "FILTER (WHERE deviceCode = 设备) " + "HAVING " + computeType(warningDO) + selectType(warningDO);
            default:
                return "WHERE deviceCode = 设备 AND " + computeType(warningDO) + selectType(warningDO);
        }
    }
}
